#region File Description
//-----------------------------------------------------------------------------
// MainMenuScreen.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Net;
using GrapplingHookGameData;
#endregion

namespace GrapplingHookGame
{
    /// <summary>
    /// The game over screen lets the player restart the game or quit. It also shows the winner.
    /// </summary>
    class GameOverScreen : MenuScreen
    {
        #region Fields
        private NetworkSession networkSession;
        private PacketWriter packetWriter;
        private PacketReader packetReader;
        private GameSession gameSession;
        private bool isWholeGameOver = false;    //if game is over or just the round
        private TimeSpan timeToNextRound;
        private int round;
        private int totalRounds;
        #endregion

        #region Initialization


        /// <summary>
        /// Constructor fills in the menu contents.
        /// </summary>
        public GameOverScreen(NetworkSession networkSession, GameSession gameSession, string winner)
            : base(gameSession.CurrentRound == gameSession.Rounds ? string.Format(Resources.GameOverMenu, winner) : string.Format(Resources.RoundOverMenu, winner))
        {
            this.networkSession = networkSession;
            this.gameSession = gameSession;
            packetWriter = new PacketWriter();
            packetReader = new PacketReader();
            this.round = gameSession.CurrentRound;
            this.totalRounds = gameSession.Rounds;
            this.isWholeGameOver = round == totalRounds;
            IsPopup = true;

            // If we are hosting a network game, add the Return to Lobby menu entry.
            if (networkSession.IsHost)
            {
                MenuEntry lobbyMenuEntry = new MenuEntry(Resources.ReturnToLobby);
                lobbyMenuEntry.Selected += ReturnToLobbyMenuEntrySelected;
                MenuEntries.Add(lobbyMenuEntry);
            }

            string leaveEntryText = networkSession.IsHost ? Resources.EndSession : Resources.LeaveSession;
            MenuEntry leaveSessionMenuEntry = new MenuEntry(leaveEntryText);
            leaveSessionMenuEntry.Selected += LeaveSessionMenuEntrySelected;
            MenuEntries.Add(leaveSessionMenuEntry);

            //start timer to next round
            timeToNextRound = new TimeSpan(0, 0, Constants.SECONDS_TO_AUTOSTART_ROUND);
        }


        #endregion

        #region Handle Input




        /// <summary>
        /// When the user cancels the main menu, ask if they want to exit.
        /// </summary>
        protected override void OnCancel()
        {
            MessageBoxScreen confirmExitMessageBox =
                                    new MessageBoxScreen(Resources.ConfirmExitSample);

            confirmExitMessageBox.Accepted += ConfirmExitMessageBoxAccepted;

            ScreenManager.AddScreen(confirmExitMessageBox);
        }


        /// <summary>
        /// Event handler for when the user selects ok on the "are you sure
        /// you want to exit" message box.
        /// </summary>
        void ConfirmExitMessageBoxAccepted(object sender, EventArgs e)
        {
            ScreenManager.Game.Exit();
        }

        /// <summary>
        /// Event handler for when the Return to Lobby menu entry is selected.
        /// </summary>
        void ReturnToLobbyMenuEntrySelected(object sender, EventArgs e)
        {
            if (networkSession.SessionState == NetworkSessionState.Playing)
            {
                networkSession.EndGame();
            }
        }


        /// <summary>
        /// Event handler for when the End/Leave Session menu entry is selected.
        /// </summary>
        void LeaveSessionMenuEntrySelected(object sender, EventArgs e)
        {
            NetworkSessionComponent.LeaveSession(ScreenManager);
        }

        #endregion

        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);

            //count down to next round
            if (!IsExiting && !isWholeGameOver)
            {
                //check if next round should start
                if (timeToNextRound.Seconds <= 0)
                {
                    //start next round
                    gameSession.StartNewRound();
                    ExitScreen();
                }
                //host counts down timer
                else if (networkSession.IsHost)
                {
                    timeToNextRound -= gameTime.ElapsedRealTime;
                }
                SendAndRecieveRoundTimer();
            }
        }

        private void SendAndRecieveRoundTimer()
        {
            //Send time to next round if host
            if (networkSession.IsHost)
            {
                packetWriter.Write(timeToNextRound.Seconds);
                LocalNetworkGamer server = (LocalNetworkGamer)networkSession.Host;
                server.SendData(packetWriter, SendDataOptions.None);
            }
            //read time to next round if client
            else
            {
                foreach (LocalNetworkGamer gamer in networkSession.LocalGamers)
                {
                    while (gamer.IsDataAvailable)
                    {
                        NetworkGamer sender;
                        gamer.ReceiveData(packetReader, out sender);
                        int seconds = packetReader.ReadInt32();
                        if (!seconds.Equals("\0")) timeToNextRound = new TimeSpan(0, 0, seconds);   //change time as long as its not a null-string
                    }
                }
            }
        }

        /// <summary>
        /// Draws the game over menu screen. This darkens down the gameplay screen
        /// that is underneath us, and then chains to the base MenuScreen.Draw.
        /// </summary>
        public override void Draw(GameTime gameTime)
        {
            base.Draw(gameTime);
            SpriteFont screenFont = ScreenManager.Font;
            SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
            spriteBatch.Begin();

            //draw round info
            Vector2 pos = Position;
            pos.Y += 100;
            pos.X += 250;
            spriteBatch.DrawString(screenFont, string.Format("Results after round {0} of {1}:", round, totalRounds), pos, FadeAlphaDuringTransition(Color.White));

            //draw wins
            pos.Y += screenFont.LineSpacing;
            foreach( NetworkGamer gamer in networkSession.AllGamers)
            {
                spriteBatch.DrawString(screenFont, gamer.Gamertag, pos, FadeAlphaDuringTransition(Color.White));
                spriteBatch.DrawString(screenFont, (gamer.Tag as Player).Wins.ToString(), pos + new Vector2(250, 0), FadeAlphaDuringTransition(Color.White));
                pos.Y += screenFont.LineSpacing;
            }

            //draw timer to next round
            if (!isWholeGameOver)
            {
                pos.Y += screenFont.LineSpacing;
                spriteBatch.DrawString(screenFont, string.Format("Next round starts in: {0}", Math.Max(0, timeToNextRound.Seconds)), pos, FadeAlphaDuringTransition(Color.White));
            }

            spriteBatch.End();
        }
    }
}
